#include "apue.h"
#include <poll.h>
#define FDARR_MAX 2

int main(int argc, char **argv) {
    int fd1[2], fd2[2], retval, i, timeout, err;
    nfds_t n;
    pid_t pid; 
    struct pollfd fdarr[FDARR_MAX];
    struct pollfd fdarr2[FDARR_MAX];
    char line[MAXLINE], strerr[MAXLINE];
    int fdarr_use[MAXLINE]= {0, 0};

    if (pipe(fd1) < 0 || pipe(fd2) < 0)
        err_sys("pipe error");
    if ((pid= fork()) < 0)
        err_sys("fork error");
    else if (pid > 0) { // parent
        close(fd1[1]); 
        close(fd2[1]);

        fdarr[0].fd= fd1[0]; 
        fdarr[0].events= POLLIN;
        fdarr[1].fd= fd2[0];
        fdarr[1].events= POLLIN;
        n= FDARR_MAX;
        timeout= 500;
        
        while (1) {
            n= 0;
            for (i=0; i<FDARR_MAX; ++i)
                if (fdarr_use[i] != -1) {
                    fdarr2[n]= fdarr[i];
                    n++;
                }

            if (n <= 0)
                break;

            if ((retval= poll(fdarr2, n, timeout)) > 0) {
                // read handle
                for (i=0; i<n; ++i) {
                    if (fdarr2[i].revents & POLLIN) {
                        switch (read(fdarr2[i].fd, line, MAXLINE)) {
                            case -1:
                                err_sys("read error");
                                break;
                            case 0:
                                printf("pipe %d close\n", i);
                                fdarr_use[i]= -1;
                                break;
                            default:
                                printf("fd %d read: %s\n", i, line);
                        } 

                    } else if ((err = fdarr2[i].revents & (POLLERR | POLLHUP | POLLNVAL))) {
                        strerr[0]= '\0';
                        if (err & POLLERR)
                            strcpy(strerr+strlen(strerr), "POLLERR ");
                        if (err & POLLHUP)
                            strcpy(strerr+strlen(strerr), "POLLHUP ");
                        if (err & POLLNVAL)
                            strcpy(strerr+strlen(strerr), "POLLNVAL");
                            

                        printf("pip %d failed: %s\n", i, strerr);
                        fdarr_use[i]= -1;
                    }
                            
                }
            } else if (retval == 0)
                ;// printf("poll timeout\n");
            else 
                err_sys("poll failed");

        }

    } else {
        close(fd1[0]); 
        close(fd2[0]);
        int j;

        i= 5, j= 2;

        while (i > 0 || j > 0) {
            sleep(1);
            sprintf(line, "hello %d", i);
            n= strlen(line);
            if (write(fd1[1], line, n) != n)
                err_sys("write error");

            if (j > 0) {
                sleep(1);
                sprintf(line, "world %d", j);
                n= strlen(line);
                if (write(fd2[1], line, n) != n)
                    err_sys("write error");

            } else if (j == 0) {
                close(fd2[1]);
            }

            i--;
            j--;            
        }
        exit(0);
    }

    return (0);
}
